package com.gd.iot.energy.service.datamanage.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.datamanage.ReportNbWaterDataPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.datamanage.ReportNbWaterDataPO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.common.vo.ChartVO;
import com.gd.iot.energy.pojo.datamanage.dto.MeterHistoryDTO;
import com.gd.iot.energy.pojo.datamanage.vo.MeterFrozenPageVO;
import com.gd.iot.energy.pojo.datamanage.vo.MeterHistoryPageVO;
import com.gd.iot.energy.pojo.datamanage.vo.MeterRealtimePageVO;
import com.gd.iot.energy.service.datamanage.ReportNbWaterDataService;
import com.gd.iot.energy.service.systemadmin.AreaOrganizationService;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomStrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReportNbWaterDataServiceImpl extends ServiceImpl<ReportNbWaterDataPOMapper, ReportNbWaterDataPO> implements ReportNbWaterDataService {

    @Autowired
    private AreaOrganizationService areaOrganizationService;

    @Resource
    private ReportNbWaterDataPOMapper reportNbWaterDataPOMapper;

    /**
     * 表数据历史表头配置文件
     */
    private static final String METER_HISTORY_LIST_COLUMN_FILE_NAME = "datamanage/meter_history_list.column";

    /**
     * 表数据实时表头配置文件
     */
    private static final String METER_REALTIME_LIST_COLUMN_FILE_NAME = "datamanage/meter_realtime_list.column";

    /**
     * 表冻结数据表头配置文件
     */
    private static final String METER_FROZEN_LIST_COLUMN_FILE_NAME = "datamanage/meter_frozen_list.column";

    @Override
    public PageVO<MeterHistoryPageVO> getNBMeterHistoryPageVO(String customerSerialnumber,
                                                              String areaName,
                                                              String archivesAddress, String imei,
                                                              String beginDate, String endDate,
                                                              Integer areaId, Integer pageSize,
                                                              Integer pageNum, String orderColumn,
                                                              String orderType) {
        IPage<MeterHistoryDTO> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MeterHistoryDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("b.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("a.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);
        queryWrapper.eq("b.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);

        if (StrUtil.isNotBlank(customerSerialnumber)) {
            queryWrapper.like("a.archives_number", customerSerialnumber.trim());
        }
        if (StrUtil.isNotBlank(areaName)) {
            queryWrapper.like("a.area_name", areaName.trim());
        }
        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("a.archives_address", archivesAddress.trim());
        }
        if (StrUtil.isNotBlank(imei)) {
            queryWrapper.eq("a.imei",imei.trim());
        }
        if (StrUtil.isNotBlank(beginDate)) {
            queryWrapper.ge(true, "a.read_time", DateUtil.beginOfDay(DateUtil.parseDate(beginDate)));
        }
        if (StrUtil.isNotBlank(endDate)) {
            queryWrapper.le(true, "a.read_time", DateUtil.endOfDay(DateUtil.parseDate(endDate)));
        }

        if (areaId != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(areaId);
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("a.area_org_id", allChildAreaIds);
            }
        }

        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }

        IPage<MeterHistoryDTO> historyDTOPage = reportNbWaterDataPOMapper.selectHistoryPage(page, queryWrapper);
        PageVO<MeterHistoryPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<MeterHistoryPageVO> meterHistoryPageVOS = convertToMeterHistoryPageVO(historyDTOPage.getRecords());
        pageVO.setData(meterHistoryPageVOS);
        pageVO.setTotal(historyDTOPage.getTotal());
        pageVO.setPages(historyDTOPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(METER_HISTORY_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    @Override
    public List<ChartVO> getNBMeterHistoryChartVO(String archivesAddress, String imei, String beginDate, String endDate, Integer areaId) {

        if(StrUtil.isBlank(archivesAddress) && StrUtil.isBlank(imei)){
            throw new MyException(ResponseCode.PARAMETER_ERROR);
        }

        if(StrUtil.isBlank(beginDate) || StrUtil.isBlank(endDate)){
            throw new MyException(ResponseCode.PARAMETER_ERROR);
        }

        QueryWrapper<MeterHistoryDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("b.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("a.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);
        queryWrapper.eq("b.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);

        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("a.archives_address", archivesAddress.trim());
        }
        if (StrUtil.isNotBlank(imei)) {
            queryWrapper.eq("a.imei",imei.trim());
        }
        if (StrUtil.isNotBlank(beginDate)) {
            queryWrapper.between( "a.read_time", DateUtil.beginOfDay(DateUtil.parseDate(beginDate)),DateUtil.endOfDay(DateUtil.parseDate(endDate)));
        }

        if (areaId != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(areaId);
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("a.area_org_id", allChildAreaIds);
            }
        }
        queryWrapper.orderByAsc("read_time");

        return reportNbWaterDataPOMapper.selectHistoryChart(queryWrapper);
    }

    @Override
    public PageVO<MeterRealtimePageVO> getNBMeterRealTimePageVO(String customerSerialnumber, String areaName, String archivesAddress, String imei, Integer areaId, Integer pageSize, Integer pageNum, String orderColumn, String orderType) {
        IPage<MeterHistoryDTO> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MeterHistoryDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("b.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("a.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);
        queryWrapper.eq("b.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);

        if (StrUtil.isNotBlank(customerSerialnumber)) {
            queryWrapper.like("a.archives_number", customerSerialnumber.trim());
        }
        if (StrUtil.isNotBlank(areaName)) {
            queryWrapper.like("a.area_name", areaName.trim());
        }
        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("a.archives_address", archivesAddress.trim());
        }
        if (StrUtil.isNotBlank(imei)) {
            queryWrapper.eq("a.imei",imei.trim());
        }

        if (areaId != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(areaId);
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("a.area_org_id", allChildAreaIds);
            }
        }

        QueryWrapper<MeterHistoryDTO> queryWrapperOrder = new QueryWrapper<>();
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            queryWrapperOrder.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }

        IPage<MeterHistoryDTO> realtimePage = reportNbWaterDataPOMapper.selectRealtimePage(page, queryWrapper,queryWrapperOrder);
        PageVO<MeterRealtimePageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<MeterRealtimePageVO> meterRealtimeOrFrozenPageVOS = convertToMeterRealtime(realtimePage.getRecords());
        pageVO.setData(meterRealtimeOrFrozenPageVOS);
        pageVO.setTotal(realtimePage.getTotal());
        pageVO.setPages(realtimePage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(METER_REALTIME_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    @Override
    public PageVO<MeterFrozenPageVO> getNBMeterFrozenPageVO(String customerSerialnumber, String areaName, String archivesAddress, String imei, String beginDate, String endDate, Integer areaId, Integer pageSize, Integer pageNum, String orderColumn, String orderType) {
        IPage<MeterHistoryDTO> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MeterHistoryDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("b.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("a.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);
        queryWrapper.eq("b.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);

        if (StrUtil.isNotBlank(customerSerialnumber)) {
            queryWrapper.like("a.archives_number", customerSerialnumber.trim());
        }
        if (StrUtil.isNotBlank(areaName)) {
            queryWrapper.like("a.area_name", areaName.trim());
        }
        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("a.archives_address", archivesAddress.trim());
        }
        if (StrUtil.isNotBlank(imei)) {
            queryWrapper.eq("a.imei",imei.trim());
        }
        if (StrUtil.isNotBlank(beginDate)) {
            queryWrapper.ge(true, "a.read_time", DateUtil.beginOfDay(DateUtil.parseDate(beginDate)));
        }
        if (StrUtil.isNotBlank(endDate)) {
            queryWrapper.le(true, "a.read_time", DateUtil.endOfDay(DateUtil.parseDate(endDate)));
        }

        if (areaId != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(areaId);
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("a.area_org_id", allChildAreaIds);
            }
        }

        QueryWrapper<MeterHistoryDTO> queryWrapperOrder = new QueryWrapper<>();
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            queryWrapperOrder.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }

        IPage<MeterHistoryDTO> frozenDTOPage = reportNbWaterDataPOMapper.selectFrozenPage(page, queryWrapper,queryWrapperOrder);
        PageVO<MeterFrozenPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<MeterFrozenPageVO> meterHistoryPageVOS = convertToMeterFrozen(frozenDTOPage.getRecords());
        pageVO.setData(meterHistoryPageVOS);
        pageVO.setTotal(frozenDTOPage.getTotal());
        pageVO.setPages(frozenDTOPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(METER_FROZEN_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    @Override
    public List<ChartVO> getNBMeterFrozenChartVO(String archivesAddress, String imei, String beginDate, String endDate, Integer areaId) {
        if(StrUtil.isBlank(archivesAddress) && StrUtil.isBlank(imei)){
            throw new MyException(ResponseCode.PARAMETER_ERROR);
        }

        if(StrUtil.isBlank(beginDate) || StrUtil.isBlank(endDate)){
            throw new MyException(ResponseCode.PARAMETER_ERROR);
        }

        QueryWrapper<MeterHistoryDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("a.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("b.is_del", SystemConsts.BooleanEnum.FALSE.value);
        queryWrapper.eq("a.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);
        queryWrapper.eq("b.energy_type", SystemConsts.EnergyTypeEnum.WATER.value);

        if (StrUtil.isNotBlank(archivesAddress)) {
            queryWrapper.like("a.archives_address", archivesAddress.trim());
        }
        if (StrUtil.isNotBlank(imei)) {
            queryWrapper.eq("a.imei",imei.trim());
        }
        if (StrUtil.isNotBlank(beginDate)) {
            queryWrapper.between( "a.read_time", DateUtil.beginOfDay(DateUtil.parseDate(beginDate)),DateUtil.endOfDay(DateUtil.parseDate(endDate)));
        }

        if (areaId != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(areaId);
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("a.area_org_id", allChildAreaIds);
            }
        }

        return reportNbWaterDataPOMapper.selectFrozenChart(queryWrapper);
    }

    /**
     * 实时数据dto转vo
     * @param records
     * @return
     */
    private List<MeterRealtimePageVO> convertToMeterRealtime(List<MeterHistoryDTO> records) {
        List<MeterRealtimePageVO> res = new ArrayList<>(records.size());
        MeterRealtimePageVO meterRealtimePageVO;
        long i = 1;
        for (MeterHistoryDTO record : records) {
            meterRealtimePageVO = new MeterRealtimePageVO();
            meterRealtimePageVO.setId(record.getId());
            meterRealtimePageVO.setSerialNum(i);
            meterRealtimePageVO.setArchivesAddress(record.getArchivesAddress());
            meterRealtimePageVO.setArchivesName(record.getArchivesName());
            meterRealtimePageVO.setArchivesNum(record.getArchivesNum());
            meterRealtimePageVO.setAreaName(record.getAreaName());
            meterRealtimePageVO.setCumulantFlow(record.getCumulantFlow());
            meterRealtimePageVO.setInstantFlow(record.getInstantFlow());
            meterRealtimePageVO.setInverseCumulantFlow(record.getInverseCumulantFlow());
            meterRealtimePageVO.setPositiveCumulantFlow(record.getPositiveCumulantFlow());
            meterRealtimePageVO.setImei(record.getImei());
            meterRealtimePageVO.setReadTime(record.getReadTime());
            meterRealtimePageVO.setMemo(record.getMemo());
            res.add(meterRealtimePageVO);
            i++;
        }
        return res;
    }

    /**
     * 冻结数据dto转vo
     * @param records
     * @return
     */
    private List<MeterFrozenPageVO> convertToMeterFrozen(List<MeterHistoryDTO> records) {
        List<MeterFrozenPageVO> res = new ArrayList<>(records.size());
        MeterFrozenPageVO meterFrozenPageVO;
        long i = 1;
        for (MeterHistoryDTO record : records) {
            meterFrozenPageVO = new MeterFrozenPageVO();
            meterFrozenPageVO.setId(record.getId());
            meterFrozenPageVO.setSerialNum(i);
            meterFrozenPageVO.setArchivesAddress(record.getArchivesAddress());
            meterFrozenPageVO.setArchivesName(record.getArchivesName());
            meterFrozenPageVO.setArchivesNum(record.getArchivesNum());
            meterFrozenPageVO.setAreaName(record.getAreaName());
            meterFrozenPageVO.setCumulantFlow(record.getCumulantFlow());
            meterFrozenPageVO.setImei(record.getImei());
            meterFrozenPageVO.setReadTime(record.getReadTime());
            meterFrozenPageVO.setReadDate(record.getReadDate());
            meterFrozenPageVO.setMemo(record.getMemo());
            res.add(meterFrozenPageVO);
            i++;
        }
        return res;
    }

    /**
     * 表数据历史 dto转vo
     * @param records
     * @return
     */
    private List<MeterHistoryPageVO> convertToMeterHistoryPageVO(List<MeterHistoryDTO> records) {
        List<MeterHistoryPageVO> res = new ArrayList<>(records.size());
        MeterHistoryPageVO meterHistoryPageVO;
        long i = 1;
        for (MeterHistoryDTO record : records) {
            meterHistoryPageVO = new MeterHistoryPageVO();
            meterHistoryPageVO.setId(record.getId());
            meterHistoryPageVO.setSerialNum(i);
            meterHistoryPageVO.setArchivesAddress(record.getArchivesAddress());
            meterHistoryPageVO.setArchivesName(record.getArchivesName());
            meterHistoryPageVO.setArchivesNum(record.getArchivesNum());
            meterHistoryPageVO.setAreaName(record.getAreaName());
            meterHistoryPageVO.setCumulantFlow(record.getCumulantFlow());
            meterHistoryPageVO.setInstantFlow(record.getInstantFlow());
            meterHistoryPageVO.setInverseCumulantFlow(record.getInverseCumulantFlow());
            meterHistoryPageVO.setPositiveCumulantFlow(record.getPositiveCumulantFlow());
            meterHistoryPageVO.setImei(record.getImei());
            meterHistoryPageVO.setReadTime(record.getReadTime());
            res.add(meterHistoryPageVO);
            i++;
        }
        return res;
    }
}
